package org.example.timer.timerwheel;

import io.netty.util.Timeout;
import io.netty.util.Timer;
import io.netty.util.TimerTask;

import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;

public class NWheelTimer implements Timer {

    /**
     * 分配的槽位
     */
    private NWheelBucket[] wheelBuckets;

    private final int mask;

    private static final int maxBuckets = 2 << 30;

    private final Thread workerThread;

    private final Worker worker = new Worker();

    private volatile long startTime;

    public NWheelTimer() {
        this(Executors.defaultThreadFactory());
    }

    public NWheelTimer(ThreadFactory threadFactory) {

        // 60秒一个槽位
        wheelBuckets = createWheel(60);
        mask = wheelBuckets.length - 1;

        workerThread = threadFactory.newThread(worker);
    }

    /**
     * 添加任务
     * @param task
     * @param delay
     * @param unit
     * @return
     */
    @Override
    public Timeout newTimeout(TimerTask task, long delay, TimeUnit unit) {
        // 算一下在当前哪个槽位
        return null;
    }

    /**
     * 停止任务
     * @return
     */
    @Override
    public Set<Timeout> stop() {
        return null;
    }

    private static NWheelBucket[] createWheel(int ticketByWheel) {
        if (ticketByWheel <= 0) {
            throw new IllegalArgumentException("ticketByWheel greater must be than 0");
        }

        if (ticketByWheel > maxBuckets) {
            throw new IllegalArgumentException("ticketByWheel must be less than 2^30");
        }

        NWheelBucket[] buckets = new NWheelBucket[ticketByWheel];
        return buckets;
    }

    /**
     * 每个槽位对象，带头指针和尾指针的链表
     */
    private static final class NWheelBucket {
        private NWheelTimeout head;
        private NWheelTimeout tail;
    }

    private static final class NWheelTimeout implements Timeout{
        @Override
        public Timer timer() {
            return null;
        }

        @Override
        public TimerTask task() {
            return null;
        }

        @Override
        public boolean isExpired() {
            return false;
        }

        @Override
        public boolean isCancelled() {
            return false;
        }

        @Override
        public boolean cancel() {
            return false;
        }
    }

    private final class Worker implements Runnable {
        @Override
        public void run() {

        }
    }
}
